package com.service.thirddatacenter.hpool.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.service.core.exception.CommonException;
import com.service.thirddatacenter.hpool.client.HPoolClient;
import com.service.thirddatacenter.hpool.client.rep.*;
import com.service.thirddatacenter.hpool.enums.MinerStatus;
import com.service.thirddatacenter.hpool.enums.ResponseCodeEnum;
import com.service.thirddatacenter.hpool.model.entity.AccountMinerEntity;
import com.service.thirddatacenter.hpool.model.entity.AccountShareEntity;
import com.service.thirddatacenter.hpool.model.entity.AccountThirdEntity;
import com.service.thirddatacenter.hpool.model.entity.MiningRecordEntity;
import com.service.thirddatacenter.hpool.service.AccountMinerService;
import com.service.thirddatacenter.hpool.service.AccountShareService;
import com.service.thirddatacenter.hpool.service.BasePlatformService;
import com.service.thirddatacenter.hpool.service.MiningRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;

@Slf4j
@Service("hpoolService")
public class HPoolServiceImpl implements BasePlatformService {

    @Autowired
    private HPoolClient hPoolClient;

    @Autowired
    private AccountMinerService accountMinerService;

    @Autowired
    private AccountShareService accountShareService;

    @Autowired
    private MiningRecordService miningRecordService;

    String language = "zh";
    String type = "chia";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncMiner(AccountThirdEntity account) {

        Integer pageSize = 15;

        HPoolResponse<MinerDetail> minerDetailResp = hPoolClient.minerDetail(language, type, account.getToken());

        checkSuccess(account, minerDetailResp, "获取矿机列表失败");

        MinerDetail minerDetail = minerDetailResp.getData();
        int minerTotalNum = minerDetail.getOffline() + minerDetail.getOnline();
        if (minerTotalNum == 0) {
            accountMinerService.update(Wrappers.lambdaUpdate(AccountMinerEntity.class)
                    .set(AccountMinerEntity::getMinerStatus, MinerStatus.delete.getCode())
                    .eq(AccountMinerEntity::getAccountId, account.getAccountId())
                    .eq(AccountMinerEntity::getMinerType, minerDetail.getType()));
        }

        Date currentDate = new Date();
        HPoolResponse<HPoolPageResponse<List<Miner>>> response = hPoolClient.pageMiner(language, type, minerTotalNum, 1, account.getToken());
        checkSuccess(account, response, "获取矿机列表失败");

        response.getData().getList().parallelStream().forEach(item -> {
            AccountMinerEntity accountMiner = accountMinerService.getByPlatformMinerId(item.getId());
            if (ObjectUtils.isEmpty(accountMiner)) {
                accountMinerService.save(AccountMinerEntity.builder()
                        .platformMinerId(item.getId())
                        .accountId(account.getAccountId())
                        .capacity(item.getCapacity())
                        .minerName(item.getMiner_name())
                        .platformUpdateTime(item.getUpdate_time())
                        .minerType(type)
                        .createTime(new Date())
                        .minerStatus(item.getOnline() ? MinerStatus.online.getCode() : MinerStatus.offline.getCode())
                        .build());
            } else {
                accountMinerService.updateById(AccountMinerEntity.builder()
                        .minerId(accountMiner.getMinerId())
                        .minerStatus(item.getOnline() ? MinerStatus.online.getCode() : MinerStatus.offline.getCode())
                        .platformUpdateTime(item.getUpdate_time())
                        .build());

            }
        });

        accountMinerService.update(Wrappers.lambdaUpdate(AccountMinerEntity.class)
                .set(AccountMinerEntity::getMinerStatus, MinerStatus.delete.getCode())
                .le(AccountMinerEntity::getUpdateTime, currentDate)
                .eq(AccountMinerEntity::getAccountId, account.getAccountId())
                .eq(AccountMinerEntity::getMinerType, type));

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncShare(AccountThirdEntity account) {

        HPoolResponse<HPoolPageResponse<List<ShareRecord>>> result = hPoolClient.pageShare(language, type, 0, 1, 1, account.getToken());
        checkSuccess(account, result, "获取贡献失败");

        Date current = new Date();
        AccountShareEntity lastShareRecord = accountShareService.getLastShareRecord(account.getAccountId(), type);
        result.getData().getList().parallelStream().forEach(item -> {
            if (ObjectUtils.isEmpty(lastShareRecord) || item.getRecord_time() > lastShareRecord.getRecordTime()) {
                accountShareService.save(AccountShareEntity.builder()
                        .accountId(account.getAccountId())
                        .shareType(item.getType())
                        .deadline(item.getDeadline())
                        .height(item.getHeight())
                        .plotterId(item.getPlotter_id())
                        .minerName(item.getMiner_name())
                        .ratio(item.getRatio())
                        .recordTime(item.getRecord_time())
                        .createTime(current)
                        .build());
            }

        });
    }

    @Override
    public void syncMiningRecord(AccountThirdEntity account) {

        HPoolResponse<HPoolPageResponse<List<MiningIncomeRecord>>> result = hPoolClient
                .pageMiningIncomeRecord(language, type, 10, 1, account.getToken());

        checkSuccess(account, result, "获取挖矿收益失败");
        Date current = new Date();

        result = hPoolClient
                .pageMiningIncomeRecord(language, type, result.getData().getTotal(), 1, account.getToken());

        MiningRecordEntity lastMiningRecord = miningRecordService.getLastMiningRecord(account.getAccountId(), type);

        result.getData().getList().parallelStream().forEach(item -> {

            if (ObjectUtils.isEmpty(lastMiningRecord) || item.getRecord_time() > lastMiningRecord.getRecordTime()) {
                miningRecordService.save(MiningRecordEntity.builder()
                        .accountId(account.getAccountId())
                        .amount(item.getAmount())
                        .miningCoin(item.getCoin())
                        .miningType(item.getType())
                        .miningName(item.getName())
                        .recordTime(item.getRecord_time())
                        .createTime(current)
                        .build());
            }

        });

    }

    public void checkSuccess(AccountThirdEntity account, HPoolResponse<?> response, String msg) {
        if (!ObjectUtils.nullSafeEquals(ResponseCodeEnum.success.getCode(), response.getCode())) {
            log.error("{}{},原因:{}", account, msg, response);
            if (ObjectUtils.nullSafeEquals(ResponseCodeEnum.not_login.getCode(), response.getCode())) {
                log.error("{}cookie失效", account);
                throw new CommonException(account.getLoginName() + " cookie失效");
            }
            throw new CommonException(msg);
        }
    }

}
